package main

import (
	"context"
	"fmt"
	"gitee.com/DonHz/electronic-business-systems/grpc_test/proto"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
	"net"
	"strconv"
	"time"
)

type Server struct {
	proto.UnimplementedHelloServer
}

func (s *Server) Hello(c context.Context, request *proto.HelloRequest) (*proto.Response, error) {
	time.Sleep(time.Second * 5)
	return &proto.Response{
		Reply: "hello " + request.Name + ", age: " + strconv.Itoa(int(request.Age)),
	}, nil
}

type Validator interface {
	Validate() error
}

func main() {
	interceptor := func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
		fmt.Println("接收到了一个新请求")
		md, ok := metadata.FromIncomingContext(ctx)
		if !ok {
			fmt.Println("get metadata error")
			return resp, status.Error(codes.Unauthenticated, "无token认证信息")
		}
		var (
			appid  string
			appkey string
		)
		if val1, ok := md["appid"]; ok {
			appid = val1[0]
		}
		if val1, ok := md["appkey"]; ok {
			appkey = val1[0]
		}
		if appid != "i am appid" || appkey != "i am appkey" {
			return resp, status.Error(codes.Unauthenticated, "token认证信息错误")
		}
		if r, ok := req.(Validator); ok {
			if err := r.Validate(); err != nil {
				return nil, status.Error(codes.InvalidArgument, "参数不符合规范")
			}
		}
		res, err := handler(ctx, req)
		fmt.Println("请求完成！")
		return res, err
	}
	opt := grpc.UnaryInterceptor(interceptor)
	g := grpc.NewServer(opt)
	proto.RegisterHelloServer(g, &Server{})
	lis, err := net.Listen("tcp", ":8080")
	if err != nil {
		panic("failed to listen: " + err.Error())
	}
	err = g.Serve(lis)
	if err != nil {
		panic("failed to start grpc: " + err.Error())
	}
}
